import pytz
from datetime import datetime, date, time

from odoo.addons.rp_courier_management.models.primary.rp_courier_mail_route import FULFILLMENT_TYPE
from ..models.primary.rp_book_pickup import BOOK_PICK_TYPE, BOOK_PICK_STATE


class BookPickupFC(object):
    """
    Model:
        满足预约单的所有算法逻辑

    Param:
        - env: odoo env

    Function:
        - judge_use_date: 判断使用的时间是否大于今天，如果不是则返回 False
        - judge_user_time: 判断使用的时段部分是否大于现在
        - shipment_create_book_pickup: 运单创建上门预约
    """

    def __init__(self, env):
        self.env = env

    def shipment_create_book_pickup(self, shipment):
        """
        运单创建上门预约

        :param shipment: 运单(rp.shipment)

        @return book_pickup: 上门预约单(rp.book.pickup)
        """
        # 获取订单中头尾城明细中，上门预约记录
        pickup = shipment.rp_ship_order_id.rp_ship_order_fulfillment_line_ids.filtered(lambda i:i.operation_type == FULFILLMENT_TYPE[1][0])
        if not pickup:
            return False

        # 预约数据
        values = {'shipment_id': shipment.id,
                  'state': BOOK_PICK_STATE[0][0],
                  'type': BOOK_PICK_TYPE[0][0],
                  'book_d': pickup.book_date,
                  'book_t': pickup.book_time_id.id,
                  'book_note': pickup.book_note,
                  'active_flag': True}
        # 运单数据
        values.update({'customer_id': shipment.customer_id.id,
                       'shipper_id': shipment.shipper_id.id,
                       'shipper_mail_route_id': shipment.shipper_mail_route_id.id,
                       'rp_parcel_ids': [(6, 0, shipment.rp_parcel_ids.ids)],
                       'parcel_total_weight': shipment.parcel_total_weight,
                       'parcel_actual_weight': shipment.parcel_actual_weight,
                       'parcel_rounded_weight': shipment.parcel_rounded_weight,
                       'parcel_total_volume': shipment.parcel_total_volume})
        # 发件人信息
        values.update({'send_country_id': shipment.send_country_id.id,
                       'send_postal_code_id': shipment.send_postal_code_id.id,
                       'send_state_id': shipment.send_state_id.id,
                       'send_city_id': shipment.send_city_id.id,
                       'send_street': shipment.send_street,
                       'send_first_name': shipment.send_first_name,
                       'send_last_name': shipment.send_last_name,
                       'send_phone': shipment.send_phone,
                       'send_address_type': shipment.send_address_type,
                       'send_company_name': shipment.send_company_name})

        rcd = self.env['rp.book.pickup'].create([values])
        rcd.confirm_book()
        return rcd

    def _find_matching_record(self, dt):
        """
        根据用户时间获取预约时间段，如果没有匹配时间段则获取最早的时间段记录

        :param dt: 时间(datetime.datetime)

        @return book_time(rp.book.time)
        """

        # 1、提取时间部分
        current_time = dt.time()

        # 2、遍历所有rp.book.time记录,检查当前时间是否在记录定义的时间范围内
        for record in self.env['rp.book.time'].search([]):
            # 创建时间对象
            start_time = time(record.start_hour, record.start_minute)
            end_time = time(record.end_hour, record.end_minute)

            if start_time <= current_time <= end_time:
                return record

        # 如果没有匹配到记录，则返回最早的一条记录
        return self.env['rp.book.time'].search([], limit=1, order='start_hour, start_minute')

    def judge_use_date(self, dt, compare='ge'):
        """
        判断使用的时间是否大于等于今天，如果不是则返回 False

        :param dt: 输入的时间，可以是 datetime.datetime 或 datetime.date
        :param compare: 比较类型：ge大于等于，gt大于

        @return: True/False，如果输入的时间大于当前日期则返回 True，否则返回 False
        """
        # 1、获取当前用户时区下的当前时间
        user_tz = pytz.timezone(self.env.user.tz)
        dtnow = datetime.now(user_tz)

        # 2、确保 dt 是 date 对象
        if isinstance(dt, datetime):
            input_date = dt.date()  # 从 datetime 提取 date 部分
        elif isinstance(dt, date):
            input_date = dt
        else:
            raise TypeError("dt must be a datetime.datetime or datetime.date instance")

        # 3、时间判断，比较日期
        if compare == 'ge':
            return True if input_date >= dtnow.date() else False
        elif compare == 'gt':
            return True if input_date > dtnow.date() else False

    def judge_user_time(self, book_t):
        """
        判断使用的时段部分是否大于等于现在，如果不是则返回 False

        :param book_t: 输入的时段(rp.book.time)

        @return: True/False
        """
        # 1、获取当前用户时区下的当前时间
        user_tz = pytz.timezone(self.env.user.tz)
        dtnow = datetime.now(user_tz)

        # 2、提取时间部分
        current_time = dtnow.time()

        # 3、使用rp.book.time创建时段
        start_time = time(book_t.start_hour, book_t.start_minute)
        end_time = time(book_t.end_hour, book_t.end_minute)

        if start_time <= current_time <= end_time or start_time > current_time:
            return True
        else:
            return False
